﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using T4Template.Model;
using T4Template.Controller;
using T4Template.Constants;
using TemplateManager;
using System.IO;
using System.Reflection;
using T4Template.CodeGenBL;
using T4Template.Dto;

namespace T4Template
{
    class Program
    {
        public static ClassModel GetClassModel()
        {
            ClassModel classModel = new ClassModel() { Id = 1, Name = "Employee" };

            AttributeModel id = new AttributeModel()
            {
                Id = 1,
                ClassModel = classModel,
                Name = "Id",
                Display = false,
                Search = false,
                SearchResult = false,
                DataType = DataType.INT,
                FieldDescription = "Data ID",
                Label = "ID",
                FieldType = ControlType.NOT_DEFINE,
                Length = 15,
                Autokey = true,
                Nullable = false,
                Pk = false,
                SeqNo = 1,//0,
                DisplayLengthInGrid = 0
            };

            AttributeModel empId = new AttributeModel()
            {
                Id = 2,
                ClassModel = classModel,
                Name = "EmpId",
                Display = true,
                Search = true,
                SearchResult = true,
                DataType = DataType.STRING,
                FieldDescription = "Employee ID",
                Label = "Employee ID",
                FieldType = ControlType.EDIT_FIELD,
                Length = 15,
                Autokey = false,
                Nullable = false,
                Pk = true,
                SeqNo = 2,//1,
                DisplayLengthInGrid = 10
            };

            AttributeModel title = new AttributeModel()
            {
                Id = 3,
                ClassModel = classModel,
                Name = "Title",
                Display = true,
                Search = false,
                SearchResult = false,
                DataType = DataType.INT,
                FieldDescription = "Employee Title's name",
                Label = "Title",
                FieldType = ControlType.RADIO_BUTTON,
                Length = 15,
                Autokey = false,
                Nullable = false,
                Pk = false,
                SeqNo = 3,//0,
                DisplayLengthInGrid = 0
            };
            AttributeModel name = new AttributeModel()
            {
                Id = 4,
                ClassModel = classModel,
                Name = "Name",
                Display = true,
                Search = true,
                SearchResult = true,
                DataType = DataType.STRING,
                FieldDescription = "Employee's name",
                Label = "Name",
                FieldType = ControlType.EDIT_FIELD,
                Length = 50,
                Autokey = false,
                Nullable = false,
                Pk = false,
                SeqNo = 4,//2,
                DisplayLengthInGrid = 15
            };

            AttributeModel surname = new AttributeModel()
            {
                Id = 5,
                ClassModel = classModel,
                Name = "Surname",
                Display = true,
                Search = false,
                SearchResult = false,
                DataType = DataType.STRING,
                FieldDescription = "Employee's surname",
                Label = "Surname",
                FieldType = ControlType.EDIT_FIELD,
                Length = 50,
                Autokey = false,
                Nullable = false,
                Pk = false,
                SeqNo = 5,//3,
                DisplayLengthInGrid = 20
            };

            AttributeModel jobTitle = new AttributeModel()
            {
                Id = 6,
                ClassModel = classModel,
                Name = "JobTitle",
                Display = true,
                Search = false,
                SearchResult = false,
                DataType = DataType.INT,
                FieldDescription = "Employee's surname",
                Label = "Job Title",
                FieldType = ControlType.DROP_DOWN_MENU,
                Length = 50,
                Autokey = false,
                Nullable = false,
                Pk = false,
                SeqNo = 6,//5,
                DisplayLengthInGrid = 0
            };

            AttributeModel status = new AttributeModel()
            {
                Id = 9,
                ClassModel = classModel,
                Name = "Status",
                Display = true,
                Search = true,
                SearchResult = true,
                DataType = DataType.INT,
                FieldDescription = "Employee's status",
                Label = "Status",
                FieldType = ControlType.RADIO_BUTTON,
                Length = 15,
                Autokey = false,
                Nullable = false,
                Pk = false,
                SeqNo = 7,//8,
                DisplayLengthInGrid = 10
            };

            AttributeModel marriedStatus = new AttributeModel()
            {
                Id = 8,
                ClassModel = classModel,
                Name = "MarriedStatus",
                Display = true,
                Search = false,
                SearchResult = false,
                DataType = DataType.INT,
                FieldDescription = "Employee's married status",
                Label = "Marrital Status",
                FieldType = ControlType.RADIO_BUTTON,
                Length = 15,
                Autokey = false,
                Nullable = false,
                Pk = false,
                SeqNo = 8,//6,
                DisplayLengthInGrid = 0
            };

            AttributeModel birthDate = new AttributeModel()
            {
                Id = 10,
                ClassModel = classModel,
                Name = "BirthDate",
                Display = true,
                Search = false,
                SearchResult = false,
                DataType = DataType.DATETIME,
                FieldDescription = "Employee's birth day",
                Label = "BirthDate",
                FieldType = ControlType.DATE_TIME_PICKER,
                Length = 30,
                Autokey = false,
                Nullable = false,
                Pk = false,
                SeqNo = 9,//7,
                DisplayLengthInGrid = 0
            };

            AttributeModel address = new AttributeModel()
            {
                Id = 7,
                ClassModel = classModel,
                Name = "Address",
                Display = true,
                Search = false,
                SearchResult = false,
                DataType = DataType.STRING,
                FieldDescription = "Employee's address",
                Label = "Address",
                FieldType = ControlType.TEXT_AREA,
                Length = 256,
                Autokey = false,
                Nullable = true,
                Pk = false,
                SeqNo = 10,//4,
                DisplayLengthInGrid = 40
            };


            classModel.AddAttribute(id);
            classModel.AddAttribute(empId);
            classModel.AddAttribute(title);
            classModel.AddAttribute(name);
            classModel.AddAttribute(surname);
            classModel.AddAttribute(jobTitle);
            classModel.AddAttribute(status);
            classModel.AddAttribute(marriedStatus);
            classModel.AddAttribute(birthDate);
            classModel.AddAttribute(address);

            return classModel;
        }

        public static CreateCodeTemplateModel GetCodeTemplateModel()
        {
            CreateCodeTemplateModel model = new CreateCodeTemplateModel();
            model.Name = "Single Table 1";
            model.CodeType = CreateCodeTemplateModel.CODE_TYPE_DOT_NET;
            model.PatternType = CreateCodeTemplateModel.PATTERN_TYPE_SINGLE_TABLE;
            model.NewVersion = true;

            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication", gen = false });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Controllers", gen = false });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Mapper", gen = true });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Models", gen = true });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Properties", gen = false });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Utilities", gen = false });
            //model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Views", gen = true });
            //model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Views\Shared", gen = false });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".WebApplication\Service References", gen = true });

            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".Dal\Dal", gen = false });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".Dal\Entities", gen = false });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".Dal\Models", gen = true });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".Dal\Properties", gen = false });

            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".Bl", gen = false });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".Bl\Dto", gen = true });
            model.AddTemplateNameSpace(new GenTemplateNameSpace { ns = @".Bl\Properties", gen = false });
            model.Comment = "Generate by SE2";
            return model;
        }

        public static string folderTemplate = @"C:\NidaProject\se2-codegenerator\T4Template\Template";

        static void Main(string[] args)
        {
            CodeGenerateController control = new CodeGenerateController();

            try
            {
                CreateCodeTemplateModel templateModel = GetCodeTemplateModel();
                CodeTemplateController codeTemplateController = new CodeTemplateController();
                codeTemplateController.CreateTemplate(templateModel);

                var genCodeModel = PreGen(control);
                control.GenerateCode(genCodeModel);

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }

        private static GenerateCodeModel PreGen(CodeGenerateController control)
        {

            GenerateCodeModel genCodeModel = new GenerateCodeModel();
            Dto.UserDto user = control.Login(new ProjectBL.LoginDto
            {
                UserName = "test",
                Password = "test"
            });
            if (user.Id != 0)
            {
                int projectId = 0;
                string projectName = "";
                var listProjectHead = control.GetProjectNameByUserId(user.Id);
                if (listProjectHead != null)
                {
                    projectId = listProjectHead[0].Id;
                    projectName = listProjectHead[0].Name;
                }
                ProjectDto project = null;
                var tempProject = control.GetProject(projectId);
                project = new ProjectDto
                {
                    CreateDate = tempProject.CreateTime,
                    DbName = tempProject.DbName,
                    DbPassword = tempProject.DbPassword,
                    DbServerName = tempProject.DbServerName,
                    DbUserName = tempProject.DbUserName,
                    Id = tempProject.Id,
                    LastUpdate = tempProject.LastUpdate,
                    Name = tempProject.Name,
                    Platform = tempProject.Platform,
                    StyleId = tempProject.StyleId,
                    UserId = tempProject.UserId,
                    Version = tempProject.Version
                };

                var listClass = control.GetClassByProjectId(projectId);
                if (listClass != null)
                {
                    genCodeModel.CodeType = CreateCodeTemplateModel.CODE_TYPE_DOT_NET;
                    genCodeModel.PatternType = CreateCodeTemplateModel.PATTERN_TYPE_SINGLE_TABLE;
                    genCodeModel.SolutionName = projectName;
                    genCodeModel.MvcProjectName = projectName + ".Web";
                    genCodeModel.BlProjectName = projectName + ".Service";
                    genCodeModel.DalProjectName = projectName + ".DAL";
                    genCodeModel.TemplateDirectory = @"C:\test\Template\ComplexWebApplication1\";
                    genCodeModel.PrimaryOutputDirectory = @"C:\test\" + projectName + @"\";
                    genCodeModel.CompleteProjectDirectory = @"C:\Test\Complete\";
                    genCodeModel.project = project;
                    genCodeModel.FolderTemplate = folderTemplate;

                    foreach (var item in listClass)
                    {
                        var objClassDto = control.GetClass(item.Id);
                        if (objClassDto.Id != 0)
                        {
                            var classTemp = new ClassModel
                            {
                                Id = objClassDto.Id,
                                Name = objClassDto.Name
                            };
                            if (objClassDto.GetAttributes() != null)
                            {
                                foreach (var attr in objClassDto.GetAttributes())
                                {
                                    classTemp.AddAttribute(new AttributeModel
                                    {
                                        Autokey = attr.Autokey,
                                        DataType = attr.DataType,
                                        Display = attr.Display,
                                        DisplayLengthInGrid = attr.DisplayLengthInGrid,
                                        FieldDescription = attr.FieldDescription,
                                        FieldType = attr.FieldType,
                                        Id = attr.Id,
                                        Label = attr.Label,
                                        Length = attr.Length,
                                        Name = attr.Name,
                                        Nullable = attr.Nullable,
                                        Pk = attr.Pk,
                                        Search = attr.Search,
                                        SearchResult = attr.SearchResult,
                                        SeqNo = attr.SeqNo
                                    });
                                }
                            }
                            genCodeModel.ClassModel.Add(classTemp);
                        }
                    }
                }
            }
            return genCodeModel;
        }
    }
}
